function $$(selector) {
    return document.querySelector(selector);
}

const offset = class {
    constructor(e) {
        function getOffsetTop(e) {
            let offset = e.offsetTop;
            if (e.offsetParent != null)
                offset += getOffsetTop(e.offsetParent);
            return offset;
        }

        function getOffsetLeft(e) {
            let offset = e.offsetLeft;
            if (e.offsetParent != null)
                offset += getOffsetLeft(e.offsetParent);
            return offset;
        }

        this.Top = getOffsetTop(e);
        this.Left = getOffsetLeft(e);
    }
}

function fixLayout() {
    const contentProportion = window.innerWidth > 960 ? 0.7 : 0.9;
    $$("#content").style.marginLeft = window.innerWidth * (1 - contentProportion) / 2 + "px";
    $$("#content").style.width = window.innerWidth * contentProportion + "px";
    $$("#left").style.width = ($$("#content").clientWidth - 300) * 0.95 + "px";
    $$("#comment").style.width = $$("#player").clientWidth + "px";
    setTimeout(fixBulletLayer, 100);
}

function fixBulletLayer() {
    $$("#bulletLayer").style.top = new offset($$("#videoPlayer")).Top + "px";
    $$("#bulletLayer").style.left = new offset($$("#videoPlayer")).Left + "px";
    $$("#bulletLayer").width = $$("#videoPlayer").clientWidth;
    $$("#bulletLayer").height = $$("#videoPlayer").clientHeight - bFixC;
}

let playing = false;
let bullets = [];
let working = {};
let topPos = 1;
let normalPos = 1;
let bulletOpc = 80;
let seeking = false;
const fontSize = 20;

let adjustingVolume = false;
let adjustingBulletOpc = false;

let fFixC = 1.0;
let vFixC = 1.0;
let bFixC = 0;

function getTopPos() {
    if (topPos * fontSize * fFixC > $$("#bulletLayer").height * 0.98) {
        topPos = 1
        return topPos;
    } else {
        topPos++;
        return topPos - 1;
    }
}

function getNormalPos() {
    if (normalPos * fontSize * fFixC > $$("#bulletLayer").height * 0.98) {
        normalPos = 1
        return normalPos;
    } else {
        normalPos++;
        return normalPos - 1;
    }
}

function updateWorking() {
    working = {};
    topPos = 1;
    for (let b in bullets) {
        if (bullets[b].time > $$("#videoPlayer").currentTime) {
            working[bullets[b].id] = bullets[b];
        }
    }
}

function updateCanvas() {
    const ctx = $$("#bulletLayer").getContext('2d');
    ctx.canvas.width = $$("#bulletLayer").width;
    ctx.canvas.height = $$("#bulletLayer").height;
    for (let b in working) {
        if (working[b].time < $$("#videoPlayer").currentTime) {
            if (working[b].type === 'top') {
                if (!working[b].hasOwnProperty('status')) {
                    working[b]['status'] = {
                        pos: {x: 0.5, y: getTopPos() * fontSize * fFixC / $$("#bulletLayer").height},
                        time: 2.5
                    }
                }
                if (working[b].time + working[b].status.time > $$("#videoPlayer").currentTime) {
                    ctx.font = fontSize * fFixC + "px bold 黑体";
                    ctx.textAlign = "center";
                    ctx.textBaseline = "middle";
                    ctx.strokeStyle = "gray";
                    ctx.strokeText(working[b].content,
                        working[b].status.pos.x * $$("#bulletLayer").width,
                        working[b].status.pos.y * $$("#bulletLayer").height);
                    ctx.fillStyle = working[b].color;
                    ctx.fillText(working[b].content,
                        working[b].status.pos.x * $$("#bulletLayer").width,
                        working[b].status.pos.y * $$("#bulletLayer").height);
                }
            }
            if (working[b].type === 'normal') {
                if (!working[b].hasOwnProperty('status')) {
                    working[b]['status'] = {
                        startPos: {
                            x: $$("#bulletLayer").width,
                            y: getNormalPos() * fontSize * fFixC / $$("#bulletLayer").height
                        }
                    }
                }
                if (working[b].velocity * $$("#bulletLayer").width *
                    ($$("#videoPlayer").currentTime - working[b].time) < $$("#bulletLayer").width * 2) {
                    ctx.font = fontSize * fFixC + "px bold 黑体";
                    ctx.textAlign = "left";
                    ctx.textBaseline = "left";
                    ctx.strokeStyle = "gray";
                    let xPos = $$("#bulletLayer").width -
                        (working[b].velocity * vFixC *
                            $$("#bulletLayer").width * ($$("#videoPlayer").currentTime - working[b].time));
                    const yPos = working[b].status.startPos.y * $$("#bulletLayer").height * 0.95 +
                        $$("#bulletLayer").height * 0.025;
                    ctx.strokeText(working[b].content,
                        xPos,
                        yPos);
                    ctx.fillStyle = working[b].color;
                    ctx.fillText(working[b].content,
                        xPos,
                        yPos);
                }
            }
        }
    }
}

function updateBullet() {
    updateCanvas();
}

function initBullet() {
    updateWorking();
    $$("#videoPlayer").addEventListener('seeked', updateWorking);
    setInterval(updateBullet, 30);
}

function hideAllBars() {
    $$("#volumeBar").style.opacity = "0%";
    $$("#volumeAdjust").style.opacity = "0%";
    $$("#bulletOpcBar").style.opacity = "0%";
    $$("#bulletOpcAdjust").style.opacity = "0%";
    adjustingBulletOpc = false;
    adjustingVolume = false;
}

function initPlayer() {
    $$("#playButton").onclick = () => {
        hideAllBars();
        if (playing) {
            $$("#videoPlayer").pause();
            $$("#playButton").src = "img/play.png";
            playing = false;
        } else {
            $$("#videoPlayer").play();
            $$("#playButton").src = "img/pause.png";
            playing = true;
        }
    }
    const updateProgressDisplay = () => {
        const tSec = (Array(2).join(0) + parseInt($$("#videoPlayer").duration % 60)).slice(-2);
        const tMin = (Array(2).join(0) + parseInt($$("#videoPlayer").duration - tSec) / 60).slice(-2);
        const cSec = (Array(2).join(0) + parseInt($$("#videoPlayer").currentTime % 60)).slice(-2);
        const cMin = (Array(2).join(0) + parseInt($$("#videoPlayer").currentTime - cSec) / 60).slice(-2);
        $$("#playTime").innerText = cMin + ":" + cSec + "/" + tMin + ":" + tSec;
        $$("#progress").style.width = ($$("#videoPlayer").currentTime / $$("#videoPlayer").duration) * 98 + "%";
    };
    $$("#videoPlayer").addEventListener("timeupdate", updateProgressDisplay);
    $$("#progressBar").onmousedown = () => {
        seeking = true;
    }
    $$("#progressBar").onclick = (e) => {
        hideAllBars();
        let pos = (e.clientX - new offset($$("#progressBar")).Left) / $$("#progressBar").clientWidth;
        $$("#videoPlayer").currentTime = $$("#videoPlayer").duration * pos;
        updateProgressDisplay();
    }
    window.addEventListener('mouseup', () => {
        seeking = false;
    })
    window.addEventListener('mousemove', (e) => {
        if (seeking) {
            let pos = (e.clientX - new offset($$("#progressBar")).Left) / $$("#progressBar").clientWidth;
            $$("#videoPlayer").currentTime = $$("#videoPlayer").duration * pos;
            updateProgressDisplay();
        }
    });

    $$("#videoPlayer").volume = 0.5;

    const updateVolumeDisplay = () => {
        if ($$("#videoPlayer").volume === 0) {
            $$("#volumeButton").src = "img/mute.png";
            $$("#volumeButton").style.marginTop = "9px";
            $$("#volumeButton").style.height = "22px";
        } else {
            $$("#volumeButton").src = "img/volume.png";
            $$("#volumeButton").style.marginTop = "5px";
            $$("#volumeButton").style.height = "32px";
        }
        $$("#volumeAdjust").style.height = 50 * $$("#videoPlayer").volume + "px";
        $$("#volumeAdjust").style.marginTop = -50 * $$("#videoPlayer").volume + "px";
    }
    $$("#volumeButton").oncontextmenu = (e) => {
        e.preventDefault();
    };
    $$("#volumeButton").onmousedown = (e) => {
        if (e.button === 2) {
            $$("#videoPlayer").volume = 0;
            updateVolumeDisplay();
        }
    };
    $$("#volumeButton").onclick = (e) => {
        if (!adjustingVolume) {
            if (adjustingBulletOpc) {
                $$("#bulletOpcBar").style.opacity = "0%";
                $$("#bulletOpcAdjust").style.opacity = "0%";
                adjustingBulletOpc = false;
            }
            $$("#volumeBar").style.opacity = "80%";
            $$("#volumeAdjust").style.opacity = "80%";
            adjustingVolume = true;
        } else {
            $$("#volumeBar").style.opacity = "0%";
            $$("#volumeAdjust").style.opacity = "0%";
            adjustingVolume = false;
        }
    }
    $$("#volumeBar").onclick = (e) => {
        if (adjustingVolume) {
            $$("#videoPlayer").volume =
                ($$("#volumeBar").clientHeight - (e.pageY - new offset($$("#volumeBar")).Top)) /
                $$("#volumeBar").clientHeight;
            updateVolumeDisplay();
        }
    }
    window.addEventListener('mousemove', updateVolumeDisplay);

    const updateBulletOpcDisplay = () => {
        if (bulletOpc === 0) {
            $$("#bulletOpcButton").src = "img/bullet_mute.png";
        } else {
            $$("#bulletOpcButton").src = "img/bullet.png";
        }
        $$("#bulletOpcAdjust").style.height = 50 * bulletOpc / 100 + "px";
        $$("#bulletOpcAdjust").style.marginTop = -50 * bulletOpc / 100 + "px";
    }
    $$("#bulletOpcButton").oncontextmenu = (e) => {
        e.preventDefault();
    };
    $$("#bulletOpcButton").onmousedown = (e) => {
        if (e.button === 2) {
            bulletOpc = 0;
            $$("#bulletLayer").style.opacity = bulletOpc + "%";
            updateBulletOpcDisplay();
        }
    };
    $$("#bulletOpcButton").onclick = (e) => {
        if (!adjustingBulletOpc) {
            if (adjustingVolume) {
                $$("#volumeBar").style.opacity = "0%";
                $$("#volumeAdjust").style.opacity = "0%";
                adjustingVolume = false;
            }
            $$("#bulletOpcBar").style.opacity = "80%";
            $$("#bulletOpcAdjust").style.opacity = "80%";
            adjustingBulletOpc = true;
        } else {
            $$("#bulletOpcBar").style.opacity = "0%";
            $$("#bulletOpcAdjust").style.opacity = "0%";
            adjustingBulletOpc = false;
        }
    }
    $$("#bulletOpcBar").onclick = (e) => {
        if (adjustingBulletOpc) {
            const pos = ($$("#bulletOpcBar").clientHeight - (e.pageY - new offset($$("#bulletOpcBar")).Top)) / $$("#bulletOpcBar").clientHeight;
            bulletOpc = pos * 100;
            $$("#bulletLayer").style.opacity = bulletOpc + "%";
            updateBulletOpcDisplay();
        }
    }
    window.addEventListener('mousemove', updateBulletOpcDisplay);

    $$("#fullscreenButton").onclick = () => {
        if (!document.fullscreenElement) {
            $$("#player").requestFullscreen();
        } else {
            document.exitFullscreen();
        }
    }

    document.addEventListener("fullscreenchange", () => {
        updateWorking();
        hideAllBars();
        if (!document.fullscreenElement) {
            fixBulletLayer();
            $$("#controls").style.marginTop = "-10px";
            fFixC = 1.0;
            vFixC = 1.0;
            bFixC = 0;
        } else {
            fixBulletLayer();
            $$("#controls").style.marginTop = "-60px";
            fFixC = 1.5;
            vFixC = 0.5;
            bFixC = 39;
        }
    })
}

window.onload = () => {
    const url = "media/bullet.json";
    const request = new XMLHttpRequest();
    request.open("get", url);
    request.send(null);
    request.onload = function () {
        if (request.status === 200) {
            bullets = JSON.parse(request.responseText);
        }
        fixLayout();
        initPlayer();
        initBullet();
    }
}
window.onresize = fixLayout;